﻿using System;
using System.Globalization;
using System.Linq;
using System.Web.Mvc;
using Telerik.Web.Mvc;
using Transport.Areas.Administrator.Models;
using Transport.Core.Models.Settings;
using Transport.Infrastructure;
using Transport.Infrastructure.Mvc;
using Transport.Services;
using Transport.Services.Infrastructure;
using Transport.Services.Settings;

namespace Transport.Areas.Administrator.Controllers
{
    [Authorize]
    public class RateMappingController : ControllerBase<IRateMappingRepository, RateMapping>
    {
        private readonly IStateProvinceRepository _stateProvinceRepository;
        private readonly IMyOfficeRepository _myOfficeRepository;
        public RateMappingController(IUnitOfWork unitOfWork, IRateMappingRepository repository,
                                    IStateProvinceRepository stateProvinceRepository, IMyOfficeRepository myOfficeRepository)
            : base(repository, unitOfWork)
        {
            _stateProvinceRepository = stateProvinceRepository;
            _myOfficeRepository = myOfficeRepository;
        }

        //
        // GET: /Administrator/RateMapping/

        public ActionResult Index()
        {
            return View();
        }

        [GridAction]
        public ActionResult GridModel(string search)
        {
            var query = from x in Repository.Search(search).Where(p => p.MyOfficeId == WorkContext.MyOfficeId)
                        join o in _stateProvinceRepository.GetAll() on x.DeliverFromId equals o.StateProvinceId
                        join p in _stateProvinceRepository.GetAll() on x.DeliverToId equals p.StateProvinceId
                        select new RateMappingModel
                        {
                            DeliverFromName = o.StateProvinceName,
                            DeliverToName = p.StateProvinceName,
                            RateColumn = x.RateColumn,
                            RateMappingId = x.RateMappingId
                        };

            var gridModel = new GridModel<RateMappingModel>
            {
                Data = query
            };
            return new JsonResult
            {
                Data = gridModel
            };
        }

        public ActionResult Create()
        {
            var stateProvinces = _stateProvinceRepository.Search("").ToList();
            var offices = _myOfficeRepository.Search("").ToList();
            var myProvince = stateProvinces.FirstOrDefault(p => p.IsMain && p.MyOfficeId == WorkContext.MyOfficeId);
            if (myProvince == null)
            {
                SetErrorNotification("Chọn tỉnh thành trực thuộc cho trung tâm này.");
                return RedirectToAction("Index", new { area = "Administrator" });
            }
            var model = new RateMappingModel()
            {
                DeliverFromId = myProvince.StateProvinceId,
                DeliverFromName = myProvince.StateProvinceName,
                StateProvincesFrom = stateProvinces.Where(p => p.MyOfficeId == WorkContext.MyOfficeId).Select(t => new GroupedSelectListItem
                {
                    GroupKey = t.MyOfficeId.ToString(),
                    GroupName = offices.FirstOrDefault(p => p.MyOfficeId == t.MyOfficeId).OfficeName,
                    Text = t.StateProvinceName,
                    Value = t.StateProvinceId.ToString(CultureInfo.InvariantCulture)
                }).ToList(),
                StateProvincesTo = stateProvinces.Select(t => new GroupedSelectListItem
                {
                    GroupKey = t.MyOfficeId.ToString(),
                    GroupName = offices.FirstOrDefault(p => p.MyOfficeId == t.MyOfficeId).OfficeName,
                    Text = t.StateProvinceName,
                    Value = t.StateProvinceId.ToString(CultureInfo.InvariantCulture)
                }).ToList()
            };

            return View(model);
        }

        public virtual ActionResult Edit(int id)
        {
            var stateProvinces = _stateProvinceRepository.Search("").ToList();
            var offices = _myOfficeRepository.Search("").ToList();
            var entity = Repository.GetById(id);
            var myProvince = stateProvinces.FirstOrDefault(p => p.IsMain && p.MyOfficeId == WorkContext.MyOfficeId);
            if (myProvince == null)
            {
                SetErrorNotification("Chọn tỉnh thành trực thuộc cho trung tâm này.");
                return RedirectToAction("Index", new { area = "Administrator" });
            }
            var model = new RateMappingModel()
            {
                StateProvincesFrom = stateProvinces.Where(p => p.MyOfficeId == WorkContext.MyOfficeId).Select(t => new GroupedSelectListItem
                {
                    GroupKey = t.MyOfficeId.ToString(),
                    GroupName = offices.FirstOrDefault(p => p.MyOfficeId == t.MyOfficeId).OfficeName,
                    Text = t.StateProvinceName,
                    Value = t.StateProvinceId.ToString(CultureInfo.InvariantCulture)
                }).ToList(),
                StateProvincesTo = stateProvinces.Select(t => new GroupedSelectListItem
                {
                    GroupKey = t.MyOfficeId.ToString(),
                    GroupName = offices.FirstOrDefault(p => p.MyOfficeId == t.MyOfficeId).OfficeName,
                    Text = t.StateProvinceName,
                    Value = t.StateProvinceId.ToString(CultureInfo.InvariantCulture)
                }).ToList(),
                DeliverFromId = entity.DeliverFromId,
                DeliverFromName = myProvince.StateProvinceName,
                DeliverToId = entity.DeliverToId,
                RateColumn = entity.RateColumn,
                RateMappingId = entity.RateMappingId,
            };
            return View("Edit", model);
        }

        [HttpPost, ValidateInput(false)]
        public virtual ActionResult Save(RateMappingModel rateMappingModel)
        {
            if (!ModelState.IsValid)
            {
                var stateProvinces = _stateProvinceRepository.Search("").ToList();
                var offices = _myOfficeRepository.Search("").ToList();
                rateMappingModel.StateProvincesFrom =
                    stateProvinces.Where(p => p.MyOfficeId == WorkContext.MyOfficeId)
                        .Select(t => new GroupedSelectListItem
                        {
                            GroupKey = t.MyOfficeId.ToString(),
                            GroupName = offices.FirstOrDefault(p => p.MyOfficeId == t.MyOfficeId).OfficeName,
                            Text = t.StateProvinceName,
                            Value = t.StateProvinceId.ToString(CultureInfo.InvariantCulture)
                        }).ToList();
                rateMappingModel.StateProvincesTo = stateProvinces.Select(t => new GroupedSelectListItem
                {
                    GroupKey = t.MyOfficeId.ToString(),
                    GroupName = offices.FirstOrDefault(p => p.MyOfficeId == t.MyOfficeId).OfficeName,
                    Text = t.StateProvinceName,
                    Value = t.StateProvinceId.ToString(CultureInfo.InvariantCulture)
                }).ToList();
                return View("Create", rateMappingModel);
            }
            //Check existed
            var modelExisted = Repository.GetAll().FirstOrDefault(p => p.DeliverFromId == rateMappingModel.DeliverFromId && p.DeliverToId == rateMappingModel.DeliverToId);
            if ((modelExisted != null && modelExisted.RateMappingId != rateMappingModel.RateMappingId) || (modelExisted != null && rateMappingModel.RateMappingId <= 0))
            {
                this.SetErrorNotification("Văn phòng đến tỉnh thành này đã được định giá.");
                var stateProvinces = _stateProvinceRepository.Search("").ToList();
                var offices = _myOfficeRepository.Search("").ToList();
                rateMappingModel.StateProvincesFrom =
                    stateProvinces.Where(p => p.MyOfficeId == WorkContext.MyOfficeId)
                        .Select(t => new GroupedSelectListItem
                        {
                            GroupKey = t.MyOfficeId.ToString(),
                            GroupName = offices.FirstOrDefault(p => p.MyOfficeId == t.MyOfficeId).OfficeName,
                            Text = t.StateProvinceName,
                            Value = t.StateProvinceId.ToString(CultureInfo.InvariantCulture)
                        }).ToList();
                rateMappingModel.StateProvincesTo = stateProvinces.Select(t => new GroupedSelectListItem
                {
                    GroupKey = t.MyOfficeId.ToString(),
                    GroupName = offices.FirstOrDefault(p => p.MyOfficeId == t.MyOfficeId).OfficeName,
                    Text = t.StateProvinceName,
                    Value = t.StateProvinceId.ToString(CultureInfo.InvariantCulture)
                }).ToList();
                return View("Create", rateMappingModel);
            }
            if (rateMappingModel.RateMappingId <= 0) //Create News
            {
                var entity = new RateMapping()
                {
                    CreatedDate = DateTime.Now,
                    DeliverFromId = rateMappingModel.DeliverFromId,
                    DeliverToId = rateMappingModel.DeliverToId,
                    IsDeleted = false,
                    RateColumn = rateMappingModel.RateColumn,
                    MyOfficeId = WorkContext.MyOfficeId
                };
                using (UnitOfWork)
                {
                    Repository.Insert(entity);
                }
            }
            else //Edit user
            {
                var entity = Repository.GetById(rateMappingModel.RateMappingId);
                entity.DeliverFromId = rateMappingModel.DeliverFromId;
                entity.DeliverToId = rateMappingModel.DeliverToId;
                entity.RateColumn = rateMappingModel.RateColumn;
                entity.MyOfficeId = WorkContext.MyOfficeId;
                using (UnitOfWork)
                {
                    Repository.Update(entity);
                }
            }

            //Save success
            this.SetSuccessNotification(string.Format("{0} đã được lưu thành công.", "Định giá vùng"));
            return RedirectToAction("Index", new { area = "Administrator" });
        }

        public ActionResult Delete(int id)
        {
            try
            {
                using (UnitOfWork)
                {
                    Repository.Delete(id);
                }
                this.SetSuccessNotification("Định giá vùng đã được xóa thành công.");
            }
            catch
            {
                this.SetErrorNotification("Định giá vùng này không thể xóa, vì đã được sử dụng!");
            }
            return RedirectToAction("index", new { area = "Administrator" });
        }
    }
}
